package org.lvxiao.example.redis.lock;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.config.RuntimeBeanReference;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;

public class DistributionSynchronizedPostProcessor
		implements BeanDefinitionRegistryPostProcessor, ImportBeanDefinitionRegistrar {

	private final String ADVISOR_BEAN_NAME = DistributionSynchronizedAdvisor.class.getName();

	private final String ADVICE_BEAN_NAME = DistributionSynchronizedAdvice.class.getName();

	@Override
	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {

	}

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		postProcessBeanDefinitionRegistry(registry);
	}

	@Override
	public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
		if (registry.containsBeanDefinition(ADVISOR_BEAN_NAME)) {
			return;
		}
		GenericBeanDefinition advisor = new GenericBeanDefinition();
		advisor.setBeanClass(DistributionSynchronizedAdvisor.class);
		advisor.setBeanClassName(ADVISOR_BEAN_NAME);
		advisor.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		advisor.getPropertyValues().add("advice", new RuntimeBeanReference(ADVICE_BEAN_NAME));
		registry.registerBeanDefinition(ADVISOR_BEAN_NAME, advisor);

		if (registry.containsBeanDefinition(ADVICE_BEAN_NAME)) {
			return;
		}
		GenericBeanDefinition advice = new GenericBeanDefinition();
		advice.setBeanClass(DistributionSynchronizedAdvice.class);
		advice.setBeanClassName(ADVICE_BEAN_NAME);
		advice.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(ADVICE_BEAN_NAME, advice);

	}

}
